package member.order.service;

import m.common.model.util.ModelQueryList;
import m.common.model.util.QueryCondition;
import m.common.service.Service;
import m.system.exception.MException;
import m.system.util.DateUtil;
import m.system.util.GenerateID;
import m.system.util.NumberUtil;
import member.base.model.UserInfo;
import member.order.model.*;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class MonthWagesService extends Service {

    public void count(UserInfo user,String yearMonth) throws Exception {
        Date ym=toDate(yearMonth);
        MonthWages model=getModel(MonthWages.class,new String[]{"*"},
            QueryCondition.and(
                QueryCondition.eq("user.oid",user.getOid()),
                QueryCondition.eq("yearMonth",yearMonth)
            )
        );
        if(null!=model){
            if(MonthWages.Status_Done.equals(model.getStatus())) throw new MException("薪资已发放，无法重新生成。");
            delete(MonthWagesDetail.class,QueryCondition.eq("monthWages.oid",model.getOid()));
            deleteModel(model);
        }
        model=new MonthWages();
        model.setOid(GenerateID.generatePrimaryKey());
        model.setBusiness(user.getBusiness());
        model.setUser(user);
        model.setYearMonth(yearMonth);
        model.setWages(user.getWages());
        model.setOrderRatio(user.getOrderRatio());
        model.setRechargeRatio(user.getRechargeRatio());
        model.setStatus(MonthWages.Status_Build);
        List<MonthWagesDetail> ds=new ArrayList<>();
        ds.addAll(build4Order(user,ym));
        ds.addAll(build4Recharge(user,ym));
        double payAmount=user.getWages(),wagesAmount=0.0,rewardAmount=0.0;
        for(MonthWagesDetail d : ds){
            d.setOid(GenerateID.generatePrimaryKey());
            d.setMonthWages(model);
            payAmount+=d.getWagesAmount()+d.getRewardAmount();
            wagesAmount+=d.getWagesAmount();
            rewardAmount+=d.getRewardAmount();
        }
        model.setPayAmount(NumberUtil.round(payAmount));
        model.setWagesAmount(NumberUtil.round(wagesAmount));
        model.setRewardAmount(NumberUtil.round(rewardAmount));
        insertModel(model);
        insertModels(ds.toArray(new MonthWagesDetail[0]));
    }
    private Date toDate(String yearMonth){
        String[] arr=yearMonth.substring(0,yearMonth.length()-1).split("年");
        if(arr[1].length()==1) arr[1]="0"+arr[1];
        return DateUtil.format(arr[0]+"-"+arr[1],"yyyy-MM");
    }
    private List<MonthWagesDetail> build4Order(UserInfo user,Date month) throws SQLException, MException {
        List<OrderInfo> ls= ModelQueryList.getModelList(OrderInfo.class,new String[]{"*"},null,
            QueryCondition.and(
                QueryCondition.ge("accountDate",DateUtil.getStartMonth(month)),
                QueryCondition.le("accountDate",DateUtil.getEndMonth(month)),
                QueryCondition.eq("status", OrderModel.StatusDone),
                QueryCondition.eq("serveUser.oid",user.getOid())
            )
        );
        Double ratio=null!=user.getOrderRatio()?user.getOrderRatio():0.0;
        List<MonthWagesDetail> detailList=new ArrayList<>();
        for(OrderInfo order : ls){
            MonthWagesDetail detail=new MonthWagesDetail();
            detail.setType(MonthWagesDetail.Type_Order);
            detail.setBusiOid(order.getOid());
            detail.setOrderNo(order.getOrderNo());
            detail.setAccountDate(order.getAccountDate());
            detail.setPayAmount(order.getPayAmount());
            detail.setWagesAmount(NumberUtil.round(order.getPayAmount()*ratio/100.0,2));
            double reward=0.0;
            List<OrderDetail> ds=ModelQueryList.getModelList(OrderDetail.class,new String[]{"num","serve.reward"},null,
                QueryCondition.eq("order.oid",order.getOid()));
            for(OrderDetail d : ds){
                reward+=d.getNum()*(null!=d.getServe().getReward()?d.getServe().getReward():0d);
            }
            detail.setRewardAmount(NumberUtil.round(reward,2));
            detailList.add(detail);
        }
        return detailList;
    }
    private List<MonthWagesDetail> build4Recharge(UserInfo user,Date month) throws SQLException, MException {
        List<MemberRecharge> ls=ModelQueryList.getModelList(MemberRecharge.class,new String[]{"*"},null,
            QueryCondition.and(
                QueryCondition.ge("accountDate",DateUtil.getStartMonth(month)),
                QueryCondition.le("accountDate",DateUtil.getEndMonth(month)),
                QueryCondition.eq("status", OrderModel.StatusDone),
                QueryCondition.eq("serveUser.oid",user.getOid())
            )
        );
        Double ratio=null!=user.getRechargeRatio()?user.getRechargeRatio():0.0;
        List<MonthWagesDetail> detailList=new ArrayList<>();
        for(MemberRecharge recharge : ls){
            MonthWagesDetail detail=new MonthWagesDetail();
            detail.setType(MonthWagesDetail.Type_Recharge);
            detail.setBusiOid(recharge.getOid());
            detail.setOrderNo(recharge.getOrderNo());
            detail.setAccountDate(recharge.getAccountDate());
            detail.setPayAmount(recharge.getPayAmount());
            detail.setWagesAmount(NumberUtil.round(recharge.getPayAmount()*ratio/100.0,2));
            detail.setRewardAmount(0.0);
            detailList.add(detail);
        }
        return detailList;
    }

    /**
     * 员工工资是否已发放
     */
    public boolean isConfirmed(String userOid,Date date) throws SQLException, MException {
        MonthWages model=getModel(MonthWages.class,new String[]{"*"},
            QueryCondition.and(
                QueryCondition.eq("user.oid",userOid),
                QueryCondition.eq("yearMonth",DateUtil.format(date,"yyyy年M月"))
            )
        );
        if(null!=model){
            return MonthWages.Status_Done.equals(model.getStatus());
        }else{
            return false;
        }
    }
}
